package com.example.fresh_fruit.service.Impl;

import com.example.fresh_fruit.dto.DeliveryDto;
import com.example.fresh_fruit.entity.Commodity;
import com.example.fresh_fruit.entity.Head;
import com.example.fresh_fruit.entity.OrderDetails;
import com.example.fresh_fruit.entity.Orders;
import com.example.fresh_fruit.mapper.CommodityMapper;
import com.example.fresh_fruit.mapper.HeadMapper;
import com.example.fresh_fruit.mapper.OrdersDetailsMapper;
import com.example.fresh_fruit.mapper.OrdersMapper;
import com.example.fresh_fruit.service.DeliveryDtoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author :飞天の鱼
 * @date : 2022/8/26 10:06
 */

@Service
@Slf4j
public class DeliveryDtoServiceImpl implements DeliveryDtoService {

    @Autowired
    private OrdersMapper ordersMapper;

    @Autowired
    private OrdersDetailsMapper ordersDetailsMapper;

    @Autowired
    private CommodityMapper commodityMapper;

    @Autowired
    private HeadMapper headMapper;

//    @Autowired
//    private DataSourceTransactionManager transactionManager;

    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public int insertDelivery(DeliveryDto deliveryDto) {
        //判断传过来的订单号是否正确
        String orderNo = deliveryDto.getOrderNo();
        //根据订单号获得此订单
        Orders selectOrderNo = ordersMapper.selectByNo(orderNo);
        if (selectOrderNo == null) {
            log.info("无此订单号，订单号错误！");
            return 1;
        }
        //获得传过来的订单包数量
        Integer commodityPackage = deliveryDto.getCommodityPackage();
        //获得此订单的团长，以及团长的提成
        Integer headId = selectOrderNo.getHeadId();
        Head head = headMapper.findById(headId);
        //获得团长的提成比例
        double proportion = head.getProportion();
        Double headMoney = commodityPackage * proportion;
        //将团长的提成费加入
        deliveryDto.setHeadMoney(headMoney);
        log.info("将此订单号的打包数量加入订单表中");
        int insertDelivery = ordersMapper.insertDelivery(deliveryDto);
        if (insertDelivery == 0) {
            log.info("打包数量加入错误");
            throw new RuntimeException("打包数量加入错误");
        }
        //判断传过来的订单详情表中的数据是否正确
        log.info("判断传过来的订单详情表中的数据是否正确");
        List<OrderDetails> orderDetailsList0 = deliveryDto.getOrderDetailsList();
        for (OrderDetails orderDetail : orderDetailsList0) {
            Commodity commodity = commodityMapper.findById(orderDetail.getCommodityId());
            if (commodity == null) {
                log.info(orderDetail.getCommodityId() + ":商品id出错或者不存在");
                return 3;
            }
            //将此订单商品的实际数量加入订单详情表中
            int i = ordersDetailsMapper.insertDelivery(orderDetail);
            if (i == 0) {
                log.info("实际数量加入出错");
//                DefaultTransactionDefinition def = new DefaultTransactionDefinition();
//                // explicitly setting the transaction name is something that can only be done programmatically
//                def.setName("SomeTxName");
//                def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
//                TransactionStatus status = transactionManager.getTransaction(def);
//                transactionManager.rollback(status);

                return 4;

            }
        }
        log.info("送货已成功！");
        return 0;
    }
}


//事务回滚方面的操作
//方法【insertDelivery】需要在Transactional注解指定rollbackFor或者在方法中显式的rollback。
//        检查信息:
//        事务场景中，抛出异常被catch后，如果需要回滚，一定要手动回滚事务。
//
//        Positive example 1：
///**
// * @author caikang
// * @date 2017/04/07
// */
//@Service
//@Transactional(rollbackFor = Exception.class)
//public class UserServiceImpl implements UserService {
//    @Override
//    public void save(User user) {
//        //some code
//        //db operation
//    }
//}
//
//
//
//    Positive example 2：
///**
// * @author caikang
// * @date 2017/04/07
// */
//@Service
//public class UserServiceImpl implements UserService {
//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public void save(User user) {
//        //some code
//        //db operation
//    }
//}
//
//
//
//    Positive example 3：
///**
// * @author caikang
// * @date 2017/04/07
// */
//@Service
//public class UserServiceImpl implements UserService {
//    @Autowired
//    private DataSourceTransactionManager transactionManager;
//
//    @Override
//    @Transactional
//    public void save(User user) {
//        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
//        // explicitly setting the transaction name is something that can only be done programmatically
//        def.setName("SomeTxName");
//        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
//
//        TransactionStatus status = transactionManager.getTransaction(def);
//        try {
//            // execute your business logic here
//            //db operation
//        } catch (Exception ex) {
//            transactionManager.rollback(status);
//            throw ex;
//        }
//    }
//}


